#include "utility.h"

std::vector<std::string> stringSplit(const std::string& str, const std::string& delim)
{
    std::size_t previous = 0;
    std::size_t current = str.find(delim);
    std::vector<std::string> elems;
    while (current != std::string::npos)
    {
        if (current > previous)
        {
            elems.push_back(str.substr(previous, current - previous));
        }
        previous = current + delim.size();
        current = str.find(delim, previous);
    }
    if (previous != str.size())
    {
        elems.push_back(str.substr(previous));
    }
    return elems;
}

std::string UTF8ToString(const std::string& utf8Data)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
    std::wstring wString = conv.from_bytes(utf8Data); // utf-8 => wstring
    std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>> convert(
        new std::codecvt<wchar_t, char, std::mbstate_t>("CHS"));
    std::string str = convert.to_bytes(wString); // wstring => string
    return str;
}

void findExtent(const Regin& _ds, const std::string& regName, Extent& extent)
{
    if (UTF8ToString(_ds.name) == regName)
    {
        std::string bd = _ds.boundary;
        std::vector<std::string> bdVec = stringSplit(bd, ",");
        extent = {atof(bdVec[0].c_str()), atof(bdVec[1].c_str()), atof(bdVec[2].c_str()), atof(bdVec[3].c_str())};
        return;
    }
    else
    {
        for (auto& r : _ds.subsets)
        {
            findExtent(r, regName, extent);
        }
    }
}

void FromJson(const nlohmann::json& jsonObj, Regin& regin)
{
    jsonObj.at("adcode").get_to(regin.adcode);
    jsonObj.at("name").get_to(regin.name);
    jsonObj.at("boundary").get_to(regin.boundary);
    for (auto& rObj : jsonObj.at("subsets"))
    {
        Regin r;
        FromJson(rObj, r);
        regin.subsets.push_back(r);
    }
}